var SYMBLETYPE = {
    "ST": "Equities",
    "Funds": "Funds",
    "Futures": "",
    "FOREX": "Forex",
    "Bonds": "",
    "XI": "Index",
    "FE": "ETF",
    "FC": "Closed-End Fund",
    "FO": "Mutual Fund",
	1:"Equities",
	2:"Option",
	3:"Futures",
	7:"Corporate Bonds",
	8:"Mutual Fund",
	9:"Government Bonds",
	10:"Index",
	13:"Strategies & Spreads",
	16:"Unspecified Bonds"
};
var ACBFieldMap = {
    "SecId": "SecId",
    "Name": "OS01W",
    "OS05K": "CUSIP",
    "ISIN": "OS05J",
    "Ticker": "OS001",
    "SecurityType": "OS010",
    "ExchangeId": "LS01Z",
    "CountryId": "XI018",
    "CurrencyId": "ST460",
    "PerformanceId": "OS06Y",
    "CategoryId": "CA675"
};
var ING_MICMapping={"159":"XLIF", "161":"XMON", "196":"MFOX", "203":"XEUE", "209":"XBRD", "160":"XPAR", "195":"XLIS", "202":"XAMS", "207":"XBRU", "204":"TOMX", "208":"MTCH", "197":"XHFT", "213":"XETR", "9":"IXUS", "11":"IXUS", "29":"IXUS", "30":"IXUS", "33":"IXUS", "190":"XDUB", "223":"MTAA", "151":"XLON", "198":"XMAD", "199":"XMAD", "2":"XBOS", "13":"XCHI", "19":"XNAS", "23":"BATY", "25":"XOTC", "26":"XCIS", "170":"XSTO", "172":"XCSE", "174":"XOSL", "176":"XHEL", "175":"XOSL", "181":"XSWX", "182":"XSWX", "185":"XSWX", "194":"XWBO"};
function setAutoCompletePath(p){
	GB_autoCompleteBoxDataManager.dataUrls=p+"acb.jsp";
}

function setAutocompleteCrossDomain(f){
	GB_autoCompleteBoxDataManager.isCrossDomain=f;
}
var QS_autoCompleteBoxDataManager = function(path, option){
    this.dataUrls ="acb.jsp";
    this.path = path;
	this.idMap={};
    this.cacheData = {};
    this.cacheKeyLen = {};
	this.lastestQueryTime = 0;
    this._callback = {};
	this.isCrossDomain = false;
	this.acbInstitutionId =(typeof(GOLBAL_DATA)!="undefined"&&typeof(GOLBAL_DATA.Instid)!="undefined")?GOLBAL_DATA.Instid:"";
	this.noCheckPermission = false;//InstitutionId
};
QS_autoCompleteBoxDataManager.prototype = {
    _requestData: function(key, reg, range, iden){
        key = encodeURIComponent(key.toLowerCase());
        var url = this.dataUrls + '?kw=' + key + '&date=' + new Date().getTime();
        $.get(url, this._dataOnArrived);//encodeURIComponent(
    },
    _dataOnArrived: function(data){
		var o=null;
		if(typeof(data)!="string"){
			o=data;
		}else{
			o = eval("(" + data.replace("\r\n","") + ")");
		}
        //var o = eval("(" + data.replace("\r\n","") + ")");
		var arrkey = "";
        var id = o.id, result = o.result, item = null;
        iData = {};
		var self = GB_autoCompleteBoxDataManager;
		var tempPidMap = {};
        for (var i = 0; i < result.length; i++) {
            item = result[i];
			if(typeof(item)=="undefined"){
				continue;
			}
			if(item.OS010.toUpperCase()=="FOREX"){
                item[ACBFieldMap["Ticker"]]=item.AC009.replace("FLIT","");
                item[ACBFieldMap["Name"]]=item.AC010;
                item[ACBFieldMap["ExchangeId"]]=item.AC011;
				//item[ACBFieldMap["ExchangeId"]]
            }else{
				item[ACBFieldMap["ExchangeId"]]=item[ACBFieldMap["ExchangeId"]].substr(6).replace(/\$/ig,"");
			}
            //!(permissiomUSCOMP&&item[ACBFieldMap["CountryId"]].toUpperCase()=="USA")&ACBPermission.indexOf(item[ACBFieldMap["ExchangeId"]])==-1
			if(item.LS01Z!=""&&!self.noCheckPermission&& typeof(QS_Permission)!= "undefined"&&        // has no permission to accesss for some exchanges.
               !QS_Permission.checkACBPermission(item[ACBFieldMap["ExchangeId"]],item[ACBFieldMap["CountryId"]].toUpperCase())){ 
				continue;    // 
			}
			if(item.OS001==""){
				item.OS001 = item.AC001;
			}
			if(item.OS010==""){
				item.OS010 = item.AC003;
			}
			if(item.OS01W==""){
				item.OS01W = item.AC020;
			}
			if(item.AC018&&item.AC003&&item.AC030){
				if(item.AC003==10&&item.AC018==200&&item.AC030==213){
					item.AC018 =item.AC030;
				}	
			}
			if(item.LS01Z==""&&item.AC018&&ING_MICMapping.hasOwnProperty(item.AC018)){
				item.LS01Z=ING_MICMapping[item.AC018];
			}
			
			if(typeof(item.OS06Y)=="undefined"||item.OS06Y==null||item.OS06Y==""){
				if(item.AC018&&item.AC003&&item.AC001){
					item.OS06Y =item.AC018+":"+item.AC003+":"+item.AC001;
				}
			}
			if(tempPidMap.hasOwnProperty(item.OS06Y)){
				continue;
			}
			if(item[ACBFieldMap["ExchangeId"]]=="XMEX"){
				continue;
			}
            arrkey = SYMBLETYPE[item.OS010];
            if (typeof(iData[arrkey]) == "undefined") {
                iData[arrkey] = [];
            }
			if(typeof(item.OS001)=="undefined"||item.OS001==""){
				continue;
			}
			self.idMap[item.OS06Y]=item;
			tempPidMap[item.OS06Y]=true;
            iData[arrkey].push(item);
        }
        self.cacheData[self._callback[id].key] = iData;
        if (parseInt(id)>self.lastestQueryTime&&typeof(self._callback[id].callback) == "function") {
			self.lastestQueryTime = parseInt(id);
            self._callback[id].callback(iData);
            self._callback[id] = null;
            delete self._callback[id];
        }
    },
    getData: function(key, requestURL, callback){
        var uKey = requestURL + "&kw=" + key.toUpperCase();
        if (!this.cacheData.hasOwnProperty(uKey)) {
            var id = new Date().getTime() + "";
            this._callback[id] = {
                callback: callback,
                key: uKey
            };
			if(this.isCrossDomain){
				$.getScript(this.dataUrls + "?" +requestURL + "&acbinstid="+this.acbInstitutionId+"&kw=" + encodeURIComponent(key) + "&id=" + id+"&callback=GB_autoCompleteBoxDataManager._dataOnArrived");
			}else{
				$.get(this.dataUrls + "?" +requestURL + "&acbinstid="+this.acbInstitutionId+"&kw=" + encodeURIComponent(key) + "&id=" + id,GB_autoCompleteBoxDataManager._dataOnArrived);
			}
			
            
        } else {
            callback(this.cacheData[uKey]);
        }
    }
};
var GB_autoCompleteBoxDataManager = new QS_autoCompleteBoxDataManager("GB_autoCompleteBoxDataManager");
var QS_autoCompleteBox = function(){
    this.subscriptions = {};
	this.scrollPanel= null;
	this.acbDom = {dom: null,wrap: null,tip:null,scroll:null};
	this.isVertical = true;
	this.mouseoverObj = null;
	this.mouseOverAble = true;
	this.init();
};
QS_autoCompleteBox.prototype = {
    /**
     * this object is singleton. Only be instantiated once
     */
    init: function(){
        if (this.acbDom.dom == null) {
            this.acbDom.dom = $("<div class='qs-autoCompleteBox'><div><div class='qs-autoCompleteBox-scroll'><div class='qs-autoCompleteBox-wrap'><table></table></div></div></div><div class='advance-search-link'><a href='javascript:void(0)'>Advanced Search</a></div><div class='acb-row-tip' style='display:none;position:absolute;'></div></div>");
            $(document.body).append(this.acbDom.dom);
            this.acbDom.wrap = this.acbDom.dom.find(".qs-autoCompleteBox-wrap");
			this.acbDom.scroll = this.acbDom.dom.find(".qs-autoCompleteBox-scroll");
			this.acbDom.table = this.acbDom.wrap.find("table");
            //this.acbDom.dom.hide();
			this.boxHide();
        }
        this._bindEvent();
    },
	hideAdvacedSearch:function(){
		this.acbDom.dom.find(".advance-search-link").remove();
	},
	/**
     * it will be called when component registration
     * @param {Object} id  input id
     * @param {Object} callback
     */
    subscription: function(id, callback, cfg){
        this.subscriptions[id] = new QS_autoCompleteBox_implement(id, callback, cfg,this);
    },
	/**
     * unSubscription the conponent
     * @param {Object} id
     */
    unSubscription: function(id){
        if (typeof(id) != "undefined" && id != null && typeof(this.subscriptions[id]) != "undefined" && this.subscriptions[id] != null) {
            this.subscriptions[id].input.unbind("autocompletebox-input");
            this.subscriptions[id] = null;
            delete this.subscriptions[id];
        }
    },
	_bindEvent: function(){
        this._mouseOver();
        this._mouseClick();
		this._documentMouseDown();
        var sf = this;
        this.acbDom.dom.find(".advance-search-link").bind("click.autocompletebox-self", function(){
            if (typeof(workspaceManager)!="undefined"&&typeof(workspaceManager.openSearchDlg) == 'function') {
                workspaceManager.openSearchDlg();
               	sf.boxHide();
            }
        })
    },
	getPidByTicker: function(id,ticker){
        if (typeof(id) != "undefined" && id != null && typeof(this.subscriptions[id]) != "undefined" && this.subscriptions[id] != null) {
           return this.subscriptions[id].getPidByTicker(ticker);
        }
    },
	_mouseOver: function(){
        var sf = this;
        this.acbDom.wrap.bind("mouseover.autocompletebox-self", function(e){
			clearTimeout(sf.mouseoverObj);
            sf.mouseoverObj = setTimeout(function(){
				if(!sf.mouseOverAble){
					return;
				}
                var o = $(e.target).closest("tr");
                sf.acbDom.wrap.find("tr").removeClass("mover");
                if (o.length > 0&&o.prop("class").indexOf("qs-autocomplete-column-title")==-1) {
                    o.addClass("mover");
                    var id = sf.acbDom.dom.attr("inputid");
                    sf.subscriptions[id].mouseOver(parseInt(o.attr("columnindex")));
                }
            }, 0)
        });
    },
	_mouseClick: function(){
        var sf = this;
        this.acbDom.wrap.bind("click.autocompletebox-self", function(e){
            sf._triggerClick();
        });
    },
	_triggerClick:function(){
		var id = this.acbDom.dom.attr("inputid");
		this.subscriptions[id]._setInputData();
	},
	_documentMouseDown:function(){
		var sf = this;
		$(document).bind("mousedown.autocompletebox-self",function(e){
			if(!$.contains(sf.acbDom.dom[0],e.target)){
				sf.boxHide();
			}
		});
	},
	boxHide:function(){
		this.acbDom.dom.hide();
		for(var o in this.subscriptions){
			if(this.subscriptions[o]&&typeof(this.subscriptions[o].cfg.onHeightChange)=="function"){   // call the onHeightChange callback.
				this.subscriptions[o].cfg.onHeightChange({width:null,height:40});
			}
		}
	},
	triggerACB: function(id){
        if (typeof(id) != "undefined" && id != null && typeof(this.subscriptions[id]) != "undefined" && this.subscriptions[id] != null) {
           this.subscriptions[id].triggerACB();
        }
    },
	changeBoxPosition:function(id){
		this.boxHide();
		if(typeof(this.subscriptions[id])!="undefined"){
			this.subscriptions[id].changeBoxPosition();
		}
	},
	setTicker:function(id,v){
		if(typeof(this.subscriptions[id])!="undefined"){
            this.subscriptions[id].setTicker(v);
        }
	},
	hideBox:function(){
		this.boxHide();
	},
	listVisible:function(){
		return this.acbDom.dom.find(":visible").length > 0;
	},
	clearValue:function(id){
		this.subscriptions[id].data.realValue="";
		this.subscriptions[id].data.lastValue="";
	}
};
var QS_autoCompleteBox_implement = function(id, callback, cfg,acbObj){
    this.id = id;
	this.acbObj = acbObj||GB_qsAutoCompleteBox;
    this.callback = callback;
	this.selectedIndex = 0;
	this.isMobile = /WebKit.+Mobile/i.test(navigator.userAgent);
	this.showCUSP = typeof(QSPC)!="undefined"&&QSPC&&typeof(QSPC.checkPermission)=="function"?QSPC.checkPermission(29.01):false;
    this.cfg = $.extend(true, {
		fixHeight:true,   // if fixHeight==true, it depends on the height of body. if fixHeight == true, it doesn't display the scrollbar.
        needClear: false,
		needRemember:true,
		focusClear:true,
		blurClear:false,
		secondClick:false,
        reCall: false,
		showAdvancedSearch:true,
		allowExchange:null,//{"USA":{}}
		hideExchange:null,
        urlCfg: {"condition":(typeof(GOLBAL_DATA)!="undefined"&&GOLBAL_DATA.Instid=="ING")?"ST,FE,FC,XI,FO,FOREX,1,2,10":"ST,FE,FC,XI,FO,FOREX"},//ST,FE,FC,XI,FO,FOREX "ST,FE,FC,XI,FO,FOREX,2"
        preciseQuery: true,
		category:["Equities", "Funds", "Forex", "Bonds", "ETF", "Closed-End Fund", "Mutual Fund", "Index","Option"]
    }, cfg);
    this.input = null;
    this.category = this.cfg.category;
    this.displayFields = [ACBFieldMap["Ticker"], ACBFieldMap["Name"], ACBFieldMap["ExchangeId"]];
    this.config = {
        moverDelay: 10,
        textChangeDelay: 300,
        hlColor: "#93A7C3",
        hlBlod: true,
        cMaxLen: 14
    };
	this.dataMap={};
    this.textChangeTimeout = null;
    this.mouseOutTimeout = null;
    this.boxIsAvailable = false;
	this.data={};
    this.searchData = {"Equities": { data: [], ml: 12, dl: 0, al: 0 },"Funds": {data: [], ml: 5, dl: 0, al: 0}, "Forex": { data: [], ml: 5,  dl: 0, al: 0 }, "Bonds": {data: [],ml: 5, dl: 0,al: 0}, "Index": { data: [],ml: 5,dl: 0,al: 0 },"ETF": {data: [],  ml: 5, dl: 0, al: 0 },"Closed-End Fund": {data: [],ml: 5, dl: 0,al: 0 }, "Mutual Fund": { data: [],  ml: 5, dl: 0,al: 0}, "Option": { data: [],  ml: 5, dl: 0,al: 0}}//key:,data-len:,max-len:,actual-len:
    //this.config = $.extend(true, this.config, option);
	this.direction = "down";
	this.isLock = false;
	this.storeValue=null;
	this.totalColumnCount = 0;
	this.url = null;
	this.scrollPanel = null;
	this.intervalScroll = [];
	this.scrollMouseOverTime = null;
	this.init();
};

QS_autoCompleteBox_implement.prototype = {
	_inputKeyUpDelay:function(e){
        if (!this.boxIsAvailable) {
            this.acbObj.acbDom.dom.css({
                top: this.input.offset().top + this.input.outerHeight() + "px",
                left: this.input.offset().left
            });
        }
        var sVal = this.input.val();
        if (typeof(QS_Validator) != "undefined" && sVal != "" && $.trim(sVal) != "" && !QS_Validator.test(sVal, 'ticker')) {
            this.input.val(QS_Validator.sliceInvalidChar(sVal, 'ticker'));
            return;
        }
        if (this.input.val() == "") {
            this._boxHide();
            return;
        }
        if (e.keyCode == 13) {
            this._keyEnter();
            return;
        }
		var requestURL = this._getRequestURL(this.cfg.urlCfg);
        this.data.realValue = this.input.val();
        this.url = requestURL + "&kw=" + this.data.realValue.toUpperCase();
		var self =this;
        GB_autoCompleteBoxDataManager.getData(this.input.val() + (this.cfg.preciseQuery ? "" : "*"), requestURL, function(data){
            if (!self.isLock) {
                self._createUI(data);
            }
        });
        this.textChangeTimeout = null;
	},
	_inputKeyUp:function(e){
        var self = this;
        if (e.keyCode == 40 || e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 13) {
            return;
        }
        this.boxIsAvailable = false;
        if (this.textChangeTimeout != null) {
            clearTimeout(this.textChangeTimeout);
        }
        this.isLock = false;
        this.textChangeTimeout = setTimeout(function(){
            self._inputKeyUpDelay(e)
        }, this.config.textChangeDelay)
	},
	_inputKeyDown:function(e){
        if (e.keyCode == 13 && this.input.val() != "" && this.selectedIndex < 1) {
			this.data.realValue = this.input.val();
            this.triggerACB();
            return;
        }
        if (!this.boxIsAvailable && e.keyCode != 13 || this.input == null || this.input.val() == "") {
            return;
        }
        if (e.keyCode == 40) {//down
            this._WASD(true);
        } else if (e.keyCode == 38) {//up
            this._WASD(false);
        } else if (e.keyCode == 37) {//left
            this._WASD(false);
        } else if (e.keyCode == 39) {//right
            this._WASD(true);
        } else if (e.keyCode == 13) {//enter
            if (this.isLock && this.cfg.secondClick) {
                this.triggerACB();
            } else {
				this._setInputData();
            }
        }
	},
    init: function(){
        var self = this;
        var dom = $("#" + self.id);
        if (!this.cfg.showAdvancedSearch) {
            this.acbObj.acbDom.wrap.find(".advance-search-link").hide();
        }
        this.input = dom;
        dom.bind("keyup.autocompletebox-input", function(e){self._inputKeyUp(e)})
        dom.bind("keydown.autocompletebox-input", function(e){self._inputKeyDown(e)});
        dom.bind("click.autocompletebox-input", function(e){
			if(self.cfg.focusClear){
				self.data.lastValue = dom.val();
				dom.val("");
			}
        });
        dom.bind("blur.autocompletebox-input", function(e){
           	if(self.cfg.needRemember&&self.data.lastValue!=null&&self.data.lastValue!=""){
				self.input.val(self.data.lastValue);
			}
			self.input.attr("editValue","");
        });
		if(!this.cfg.fixHeight&&typeof(this.cfg.onHeightChange)=="function"){   // call the onHeightChange callback.
			this.cfg.onHeightChange({width:null,height:40});   // init the height to 0;
		}
		this._setResultCount(this.cfg.searchDataCfg);
    },
	_setResultCount:function(cfg){
		if(cfg){
			for(var k in cfg){
				for(var l in cfg[k]){
					this.searchData[k][l]=cfg[k][l];
				}
			}
		}
	},
    changeBoxPosition: function(){
        if (this.input != null) {
            this._adjustPos();
        }
    },
	getPidByTicker:function(ticker){
		var data = GB_autoCompleteBoxDataManager.cacheData[this.url],temp = null,d = null;
		if(typeof(data)=="undefined"){
			return null;
		}
        for (var i = 0; i < this.cfg.category.length; i++) {
            temp = data[this.cfg.category[i]];
            if (typeof(temp) != "undefined"&& temp != null) {
                for (var j = 0; j < temp.length; j++) {
					if(!temp[j]||!temp[j]["OS001"]){
						continue;
					}
                    if (temp[j]["OS001"] == ticker.toUpperCase()) {
                        d = temp[j];
                    }
                    if (d != null && typeof(d["XI018"]) != "undefined" && d["XI018"] == "USA") {
                        break;
                    }
                }
            }
            if (d != null) {
				return {pid:d["OS06Y"],ticker:d["OS001"],exch:d["LS01Z"]};
                break;
            }
        }
		return null;
	},
    hideBox: function(){
        if (typeof(this.acbObj.acbDom.dom) != "undefined" && this.acbObj.acbDom.dom != null) {
            this.acbObj.acbDom.dom.hide();
        }
        this._boxHide();
    },
	setTicker:function(v){//{ticker:,exch:,pid:}
        if (!v || !v.ticker) {
            return;
        }
        this.data.realValue = v.ticker;
        var tickerStr = '';
        if (v.pid != null && gIdMap[v.pid]) {
            tickerStr = gData[gIdMap[v.pid]].clientTicker || gData[gIdMap[v.pid]].ticker
        }else{
            tickerStr = v.clientTicker || v.ticker;
        }
        
		this.input.val(tickerStr.toUpperCase());
	},
    triggerACB: function(){
        if (typeof(this.callback) == "function") {
			var data = GB_autoCompleteBoxDataManager.cacheData[this.url],temp = null,d = null;
			if(this.stroeValue!=null){
				this._execCallBack(this.stroeValue.pid,this.stroeValue.info);
			}else{
                if (typeof(data) != "undefined") {
                    for (var i = 0; i < this.cfg.category.length; i++) {
                        temp = data[this.cfg.category[i]];
                        if (typeof(temp != null) && temp != null) {
                            for (var j = 0; j < temp.length; j++) {
                                if (temp[j]["OS001"] == this.data.realValue.toUpperCase()) {
                                    d = temp[j];
                                }
                                if (d != null && typeof(d["XI018"]) != "undefined" && d["XI018"] == "USA") {
                                    break;
                                }
                            }
                        }
                        if (d != null) {
                            break;
                        }
                    }
                }
                if (d != null) {
                    this._execCallBack(d["OS06Y"], {
                        ticker: d["OS001"],
                        exch: d["LS01Z"]
                    });
                } else {
					if(this.data.realValue){
						this._execCallBack(this.data.realValue.toUpperCase(), {
							ticker: this.data.realValue.toUpperCase(),
							exch:""
						});
					}else{
						this._execCallBack("", {
							ticker: "",
							exch:""
						});
					}
					 
                }
			}
			
        }
    },
    listVisible: function(){
        return this.acbObj.acbDom.dom.find(":visible").length > 0;
    },
	mouseOver:function(y){
		this.selectedIndex = y;
	},
    _getRequestURL: function(cfg){
        var url = "";
        for (var o in cfg) {
            if (o != null) {
                url += "&" + o + "=" + cfg[o];
            }
        }
        return url;
    },
    _pretreatmentData: function(data){
		var tempMatch="";
        this.boxIsAvailable = false;
        if (this.input == null || typeof(data) == "undefined" || data == null || data.length == 0) {
            return;
        }
        var ival = this.input.val();
        if (ival == "") {
            return;
        }
        if (ival.indexOf("$") != -1) {
            ival = "\\$" + ival.substr(1, ival.length);
        }
        var rgx = new RegExp(ival, "i");
		var rgxPrecise = new RegExp("^"+ival+"$", "i");
        var cat = this.category, tc = null, td = null, tmatch = null, flag = false;
        tex = null, sd = null, arr1 = [], arr2 = [];
        for (var i = 0; i < cat.length; i++) {
            tc = cat[i], td = data[tc];
            sd = this.searchData[tc];
            sd.data.length = 0, sd.dl = 0, sd.al = 0, arr1 = [], arr2 = [];
            if (typeof(td) != "undefined" && td != null && td.length > 0) {
                for (var j = 0; j < td.length; j++) {
                    flag = false;//allowExchange
					var _country =td[j]["XI018"],_exchangeId = td[j]["AC018"];
					if(_country&&this.cfg.allowExchange!=null){
						if(this.cfg.allowExchange.hasOwnProperty(_country)){
							if(_exchangeId&&this.cfg.allowExchange[_country]!=null&&!this.cfg.allowExchange[_country].hasOwnProperty(_exchangeId)){
								continue;
							}
						}else{
							continue;
						}
					}
					if(_country==""&&this.cfg.allowExchange!=null){
						continue;
					}
					/*
					if(td[j]["XI018"]){
						if(!this.securityType.hasOwnProperty(td[j]["XI018"])||his.securityType[td[j]["XI018"]]!==true){
							continue;
						}
					}
					*/
                    tex = $.extend(true, {}, td[j]);
                    tex.origin = tex[this.displayFields[0]];
					tex.ticker = tex.origin;
                    if (tex.origin == "") {
                        continue;
                    }
					if(tex["SecId"]){
						this.dataMap[tex["SecId"]] = td[j];
					}
					if(typeof(tex["SecId"])=="undefined"||tex["SecId"]==""){
						this.dataMap[td[j].OS06Y]=td[j];
					}
                    tmatch = td[j][this.displayFields[0]].match(rgx);
                    if (tmatch != null) {
                        flag = true;
                        tex.ticker = tex[this.displayFields[0]].replace(rgx, "<b class='highlight'>" + tmatch[0] + "</b>");
                        arr1.push(tex);
                    } else {
                        tmatch = tex[this.displayFields[1]].match(rgx);
                        if (tmatch != null) {
                            flag = true;
                            tex[this.displayFields[1]] = td[j][this.displayFields[1]].replace(rgx, "<b class='highlight'>" + tmatch[0] + "</b>");
                            arr2.push(tex);
                        }else if(this.showCUSP){
							flag = true;
							var k = "459200101";
							if(tex["OS05K"]&&ival.toUpperCase()==tex["OS05K"].toUpperCase()){
								tex.ticker = "<b class='highlight'>" + tex[this.displayFields[0]] + "</b>";
							}

							arr2.push(tex);
						}
                    }
					tempMatch +="#"+td[j][this.displayFields[0]]+"_"+td[j][this.displayFields[2]]+"#";
                    if (flag) {
                        this.boxIsAvailable = true;
                    }
                }
                sd.data = arr1.concat(arr2);
                sd.dl = sd.data.length;
                sd.al = sd.dl > sd.ml ? sd.ml : sd.dl;
            }
        }
    },
    _createUI: function(data){
        this.selectedIndex = 0;
        this.direction = "down";
        this._pretreatmentData(data);
        if (!this.boxIsAvailable) {
            this._boxHide();
            return;
        }
        this.acbObj.acbDom.table.html(this._buildContentUI(this.searchData));
        this.acbObj.acbDom.dom.show();
		//console.log(this.acbObj.acbDom.table.height()+"|"+this.acbObj.acbDom.table.width());
		if(typeof(this.cfg.onHeightChange)=="function"){   // call the onHeightChange callback.
			this.cfg.onHeightChange({width:this.acbObj.acbDom.table.width(),height:this.acbObj.acbDom.table.height()+40});
		}
		this.acbObj.acbDom.dom.attr("inputid",this.id);
        this._adjustPos();
    },
    _buildContentUI: function(searchData){
        var strArr = [], tc = null, rowCount = 0, td = null,exchName="";
        for (var i = 0; i < this.category.length; i++) {
            tc = this.category[i];
            td = searchData[tc];
            if (td.al == 0) {
                continue;
            }
			var _tempSecid = "";
			strArr.push("<tr columnIndex='-"+strArr.length+"' class='qs-autocomplete-column-title'><td colspan='3' >"+tc+"</td></tr>");
            for (var j = 0; j < searchData[tc].al; j++) {
                exchName = this._filterFields("ExchangeId", td.data[j][this.displayFields[2]],td.data[j]["AC018"]);
				//(typeof(td.data[j]["AC028"])=="undefined"?"":"."+td.data[j]["AC028"])+
                var tempStr = "";//"<tr columnIndex='"+strArr.length+"' realValue='"+td.data[j].origin+"' secid='"+td.data[j]["SecId"]+"' pid='"+td.data[j].OS06Y+"' miccode='"+td.data[j][this.displayFields[2]]+"'><td class='qs-autocomplete-col-ticker'>" + td.data[j].ticker + "</td><td class='qs-autocomplete-col-name'>" + td.data[j][this.displayFields[1]] + "</td><td class='acb-right'>" + exchName + "</td></tr>";
                /*
				if(this.isMobile){
					 tempStr = "<tr columnIndex='"+strArr.length+"' realValue='"+td.data[j].origin+"' secid='"+td.data[j]["SecId"]+"' pid='"+td.data[j].OS06Y+"' miccode='"+td.data[j][this.displayFields[2]]+"'><td class='qs-autocomplete-col-ticker'>" + td.data[j].ticker + "</td><td class='qs-autocomplete-col-name'>" + td.data[j][this.displayFields[1]] + "</td></tr>";
				}else{
					 tempStr = "<tr columnIndex='"+strArr.length+"' realValue='"+td.data[j].origin+"' secid='"+td.data[j]["SecId"]+"' pid='"+td.data[j].OS06Y+"' miccode='"+td.data[j][this.displayFields[2]]+"'><td class='qs-autocomplete-col-ticker'>" + td.data[j].ticker + "</td><td class='qs-autocomplete-col-name'>" + td.data[j][this.displayFields[1]] + "</td><td class='acb-right'>" + exchName + "</td></tr>";
				}
				*/
				_tempSecid=td.data[j]["SecId"];
				if(typeof(_tempSecid)=="undefined"||!_tempSecid||_tempSecid==""){
					_tempSecid=td.data[j].OS06Y;
				}
				tempStr = "<tr columnIndex='"+strArr.length+"' realValue='"+td.data[j].origin+"' secid='"+_tempSecid+"' pid='"+td.data[j].OS06Y+"' miccode='"+td.data[j][this.displayFields[2]]+"'><td class='qs-autocomplete-col-ticker'>" + td.data[j].ticker + "</td><td class='qs-autocomplete-col-name'>" + td.data[j][this.displayFields[1]] + "</td><td class='acb-right'>" + exchName + "</td></tr>";
				strArr.push(tempStr);
            }
        }
		this.totalColumnCount = strArr.length;
        return strArr.join("");
    },
	_filterFields:function(field,s,exchId){
		if(typeof(s)=="undefined"){
			return;
		}
		if(field=ACBFieldMap["ExchangeId"]){
			if(typeof(exchId)!="undefined"&& typeof(gExangeIdShortNameMap)!="undefined" &&gExangeIdShortNameMap&&gExangeIdShortNameMap[exchId]){
				s=gExangeIdShortNameMap[exchId];
			}else if(typeof(gMICExangeMap)!="undefined"&&typeof(gMICExangeMap[s])!="undefined"){
				s=gMICExangeMap[s];
			}
		}
		return s.replace(/\$/ig,"");
	},
    _adjustPos: function(){
        var acbox = this.acbObj, inputOffset = this.input.offset(), acboxOffset = acbox.acbDom.dom.offset(), inputOutHeight = this.input.outerHeight(true);
        var _top = inputOffset.top-$(document.body).scrollTop();
		var _acb_height =0;
		
        var winHeight = $(window).height(),winWidth =$(window).width() ;
        if (winHeight == null) {
            winHeight = 0;
        }
		var adSearchHeight = 0;
		if(acbox.acbDom.dom.find(".advance-search-link").length>0){
			adSearchHeight = acbox.acbDom.dom.find(".advance-search-link").outerHeight(true);
		}
		var acbDomTotalHeight = 0;
		if (this.input != null) {
			if((winHeight-_top)<80&&this.cfg.fixHeight){
				_acb_height=_top - adSearchHeight;
				var upTop = _top-(this.acbObj.acbDom.table.height()+adSearchHeight);
				if(upTop<0){  // up
					upTop = 0;
				}
				acbox.acbDom.dom.css({
					top: upTop + "px",
					left: inputOffset.left
				});
				acbDomTotalHeight = this.acbObj.acbDom.table.height()+adSearchHeight;
			}else{
				acbox.acbDom.dom.css({
					top: _top + inputOutHeight + "px",
					left: inputOffset.left
				});
				acbDomTotalHeight = this.acbObj.acbDom.table.height() + _top + inputOutHeight;
				_acb_height =winHeight - (_top + inputOutHeight+adSearchHeight+2);
			}
        }
        
		var acbDomWidth = 0;
        if (acbDomTotalHeight > winHeight&&this.cfg.fixHeight) {  // if fixHeight == true display the scrollbar.
            if (!this.acbObj.scrollPanel) {
                this.acbObj.scrollPanel = new Util.ScrollPanel(this.acbObj.acbDom.scroll);
            }
			acbDomWidth=this.acbObj.acbDom.table.width() + 12+2;
			if(acbDomWidth>winWidth&&this.isMobile){
				acbDomWidth=winWidth;
			}
            this.acbObj.scrollPanel.reSize(acbDomWidth,_acb_height );
        } else {
            if (this.acbObj.scrollPanel) {
				acbDomWidth=this.acbObj.acbDom.table.width();
				if(acbDomWidth>winWidth&&this.isMobile){
					acbDomWidth=winWidth;
				}
				var self = this;
				if($.browser.msie){
				//acbox.acbDom.wrap.css({"width":this.acbObj.acbDom.table.width()});
				this.acbObj.scrollPanel.reSize(acbDomWidth, this.acbObj.acbDom.table.height()+2);
				/*
					acbox.acbDom.wrap.css({"width":this.acbObj.acbDom.table.width()});
					setTimeout(function(){
						acbDomWidth=self.acbObj.acbDom.table.width();
						if(acbDomWidth>winWidth&&self.isMobile){
							acbDomWidth=winWidth;
						}
						self.acbObj.scrollPanel.reSize(acbDomWidth, self.acbObj.acbDom.table.height()+2);
					},300)
					*/
				}else{
					this.acbObj.scrollPanel.reSize(acbDomWidth, this.acbObj.acbDom.table.height());
					
				}
                //this.acbObj.scrollPanel.reSize(acbDomWidth, this.acbObj.acbDom.table.height());
            }else{
				acbDomWidth=this.acbObj.acbDom.table.width();
			}
        }
		//alert(this.isMobile);
		//alert(/WebKit.+Mobile/i.test(navigator.userAgent));
		//if(acbDomWidth>0){//&&!this.isMobile
			if(winWidth<(acbDomWidth+acboxOffset.left)){
				acbox.acbDom.dom.css({
                left: winWidth-acbDomWidth-2
            });
			}
		//}
		
    },
	_getAvailableIndex:function(i,isDown){
        if (i < 0||this.acbObj.acbDom.wrap.find("tr[columnindex='" + (-i) + "']").length> 0) {
            return this._getAvailableIndex(Math.abs(i) + (isDown?1:-1), isDown);
        } else {
            if (this.acbObj.acbDom.wrap.find("tr[columnindex='" + i + "']").length > 0) {
                return i;
            } else {
                return isDown?1:this.acbObj.acbDom.wrap.find("tr").length-1;
            }
        }
	},
	_WASD:function(isDown){
		var obj = this.acbObj.acbDom.wrap;
		this.selectedIndex = this._getAvailableIndex(Math.abs(this.selectedIndex) + (isDown?1:-1),isDown);
		if(this.acbObj.scrollPanel){
            var per = this.selectedIndex / (this.totalColumnCount - 1);
			this.acbObj.mouseOverAble = false;
			if(this.scrollMouseOverTime){
				clearTimeout(this.scrollMouseOverTime);
			}
            this.acbObj.scrollPanel.scrollbarY.scrollPercentTo(per);
			var self = this;
			this.scrollMouseOverTime =setTimeout(function(){
				self.acbObj.mouseOverAble=true;
			},500)
		}
        obj.find("tr").removeClass("mover");
		var liObj=obj.find("tr[columnindex='" + this.selectedIndex + "']");
		liObj.addClass("mover");
	},
    _setInputData: function(){
        this.isLock = true;
        var obj = this.acbObj.acbDom.wrap.find("tr[columnindex='" + this.selectedIndex + "']");
        var v1 = obj.attr("miccode"), v2 = obj.attr("realValue"), v3 = obj.attr("pid"),secid = obj.attr("secid");
        if (typeof(v2) != "undefined") {
            if (v1 == "FLIT") {
                //v2 += v1; //amy report a bug:Auto-complete: When select forex from the auto-complete, it will display "FLIT" flow the tickers 
                if (v3 == "") {
                    v3 = "245:" + v2+v1;
                }
            }
			var allData = {ticker: v2,exch: v1};
			if(secid&&this.dataMap[secid]!="undefined"&&this.dataMap[secid]!=null){
				allData = $.extend(true,allData,this.dataMap[secid]);
			}
            if (!this.cfg.secondClick) {
                this._execCallBack(v3,allData );
            } else {
                if (this.storeValue == null) {
                    this.stroeValue = {
                        pid: v3,
                        info: allData
                    };
                    this.input.val(v2);
                } else {
                    this._execCallBack(this.stroeValue.pid, this.stroeValue.info);
                }
            }
        }
        this._boxHide();
    },
    _execCallBack: function(val,v){
		this.isLock = true;
        if (typeof(this.callback) == "function") {
			if(!this.cfg.needClear&&typeof(v)!="undefined"){
				this.input.val(v.ticker);
			}else{
				this.input.val("");
			}
			this.callback(val,v);//(v1+":"+v2)
			this.data.realValue ="";// v.ticker;
			this.data.lastValue =v.ticker;
			this.stroeValue = null;
			
        }
		this._boxHide();
		this.selectedIndex=0;
    },

    _boxHide: function(){
        if (typeof(this.acbObj.acbDom.dom) != "undefined" && this.acbObj.acbDom.dom != null) {
            this.acbObj.acbDom.dom.hide();
        }
		this.selectedIndex = 0;
		if(typeof(this.cfg.onHeightChange)=="function"){   // call the onHeightChange callback.
			this.cfg.onHeightChange({width:null,height:40});
		}
    },
    clear: function(){
        this._unbindEvent();
        for (var f in this) {
            if (!f || f == 'clear') {
                continue;
            }
            this[f] = null;
            delete this[f];
        }
    }
};
var GB_qsAutoCompleteBox = new QS_autoCompleteBox();
